using NaughtyAttributes;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Physics;
using Unity.Physics.Authoring;
using Unity.Transforms;
using UnityEngine;
using UnityEngine.AI;
using BoxCollider = Unity.Physics.BoxCollider;
using CapsuleCollider = Unity.Physics.CapsuleCollider;
using SphereCollider = Unity.Physics.SphereCollider;
#if UNITY_EDITOR
#endif

namespace Gj
{
    public class TerrainMesh : MonoBehaviour
    {
        public string key;
        public string category;
        public int id;
        public int template;
        public int elementId;
        public string elementType;
        public bool physics;
        public bool grid;
        public string showName;
        public TerrainCategory categoryManager;

        [SelectArea] public int area;

        private MeshFilter _meshFilter;
        private NavMeshBuildSource _source;
        private Entity entity;

        private MeshFilter MeshFilter
        {
            get
            {
                if (_meshFilter == null) _meshFilter = GetComponent<MeshFilter>();
                return _meshFilter;
            }
        }

        private void Awake()
        {
            if (physics) entity = ObjectService.EntityManager.CreateEntity();
        }

        private void OnDestroy()
        {
        }

        public void UpdateNavMesh()
        {
            _source.transform = transform.localToWorldMatrix;
        }

        public virtual NavMeshBuildSource GetNavMesh()
        {
            return grid ? GetGridNavMesh() : GetRealNavMesh();
        }

        protected virtual int GetArea()
        {
            return area;
        }
        
        [Button]
        public void NameToKey()
        {
            key = gameObject.name;
        }

        [Button]
        public void KeyToName()
        {
            gameObject.name = key;
        }

        public string GetElementKey()
        {
            return string.Format("{0}-{1}", elementType, key);
        }

        public bool HasCategory(string s)
        {
            if (s == "") return false;
            if (categoryManager == null) return false;
            return categoryManager.HasObj(s);
        }

        public int GetCategoryIndex()
        {
            if (categoryManager != null) return categoryManager.GetIndex(category);
            return -1;
        }

        public GameObject GetCategoryObj(string k)
        {
            if (categoryManager != null) return categoryManager.GetObj(k);
            return null;
        }

        public GameObject GetCategoryObj(int i)
        {
            if (categoryManager != null) return categoryManager.GetObj(i);
            return null;
        }

        private NavMeshBuildSource GetRealNavMesh()
        {
            _source = new NavMeshBuildSource();
            _source.shape = NavMeshBuildSourceShape.Mesh;
            if (MeshFilter != null) _source.sourceObject = MeshFilter.sharedMesh;
            _source.transform = transform.localToWorldMatrix;
            _source.area = GetArea();
            return _source;
        }

        private NavMeshBuildSource GetGridNavMesh()
        {
            _source = new NavMeshBuildSource();
            _source.shape = NavMeshBuildSourceShape.Mesh;
            _source.sourceObject = GetGridMesh();
            _source.transform = transform.localToWorldMatrix;
            _source.area = GetArea();
            return _source;
        }

        private Mesh GetGridMesh()
        {
            return ModelTools.gridMesh;
        }

        public void MakeCollider()
        {
            var manager = ObjectService.EntityManager;
            manager.AddComponentData(entity,
                new LocalTransform { Position = transform.position, Rotation = transform.rotation });
            manager.AddComponentData(entity, new TerrainData());
            var physicsCollider = new PhysicsCollider();
            var authoring = GetComponent<PhysicsStepAuthoring>();
            // var _quaternion = quaternion.identity;
            // switch (authoring.ShapeType)
            // {
            //     case ShapeType.Box:
            //         var box = authoring.GetBoxProperties();
            //         box.Size = new float3(box.Size.x * transform.localScale.x, box.Size.y * transform.localScale.y,
            //             box.Size.z * transform.localScale.z);
            //         physicsCollider.Value = BoxCollider.Create(box);
            //         break;
            //     case ShapeType.Capsule:
            //         var capsule = authoring.GetCapsuleProperties();
            //         capsule.Radius = capsule.Radius * transform.localScale.x;
            //         physicsCollider.Value = CapsuleCollider.Create(capsule.ToRuntime());
            //         break;
            //     case ShapeType.Sphere:
            //         var sphere = authoring.GetSphereProperties(out _quaternion);
            //         sphere.Radius = sphere.Radius * transform.localScale.x;
            //         physicsCollider.Value = SphereCollider.Create(sphere);
            //         break;
            // }

            manager.AddComponentData(entity, physicsCollider);
        }
    }
}